home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / kill_user.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  6KB  |  212 lines

  1. /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    $Id: kill_user.c,v 1.50 2001/02/15 08:39:45 drscholl Exp $ */
  6.  
  7. /* Modified 30/05/01 : Added include "extrasocket.h" with inlines for a few
  8.       for Amiga port : bsdsocket.library functions not emulated by ixemul
  9. */
  10.  
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #include <stdio.h>
  14. #include <sys/types.h>
  15. #ifndef WIN32
  16. #include <sys/socket.h>
  17. #endif
  18. #include <netinet/in.h>
  19. #include <arpa/inet.h>
  20. #include "opennap.h"
  21. #include "debug.h"
  22.  
  23. #include "extrasocket.h"
  24.  
  25. /* send a message to all local mods */
  26. void
  27. notify_mods (unsigned int level, const char *fmt, ...)
  28. {
  29.     int     len;
  30.     va_list ap;
  31.     LIST   *list;
  32.     CONNECTION *con;
  33.  
  34.     va_start (ap, fmt);
  35.     vsnprintf (Buf + 4, sizeof (Buf) - 4, fmt, ap);
  36.     va_end (ap);
  37.     set_tag (Buf, MSG_SERVER_NOSUCH);
  38.     len = strlen (Buf + 4);
  39.     set_len (Buf, len);
  40.     for (list = Mods; list; list = list->next)
  41.     {
  42.         con = list->data;
  43.         if (con->uopt->usermode & level)
  44.             queue_data (con, Buf, len + 4);
  45.     }
  46. }
  47.  
  48. /* request to kill (disconnect) a user */
  49. /* [ :<nick> ] <user> [ "<reason>" ] */
  50. HANDLER (kill_user)
  51. {
  52.     char   *av[2];
  53.     int     ac = -1;
  54.     USER   *sender, *user;
  55.     char   *sender_name;
  56.  
  57.     (void) tag;
  58.     (void) len;
  59.     ASSERT (validate_connection (con));
  60.  
  61.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  62.         return;
  63.     if (pkt)
  64.         ac = split_line (av, FIELDS (av), pkt);
  65.     if (ac < 1)
  66.     {
  67.         if (ISUSER (con))
  68.             send_cmd (con, MSG_SERVER_NOSUCH,
  69.                       "kill failed: too few parameters");
  70.         return;
  71.     }
  72.     user = hash_lookup (Users, av[0]);
  73.     if (!user)
  74.     {
  75.         if (ISUSER (con))
  76.             send_cmd (con, MSG_SERVER_NOSUCH, "kill failed: no such user");
  77.         return;
  78.     }
  79.     ASSERT (validate_user (user));
  80.  
  81.     /* check for permission */
  82.     if (sender && user->level >= sender->level && sender->level < LEVEL_ELITE)
  83.     {
  84.         if (ISUSER (con))
  85.             send_cmd (con, MSG_SERVER_NOSUCH,
  86.                       "kill failed: permission denied");
  87.         return;
  88.     }
  89.  
  90.     if (ac > 1)
  91.         truncate_reason (av[1]);
  92. #define REASON ((ac > 1) ? av[1] : "")
  93.  
  94.     kill_user_internal (con, user, sender_name, sender, "%s", REASON);
  95. }
  96.  
  97. void
  98. kill_user_internal (CONNECTION * con,
  99.                     USER * user,
  100.                     const char *sender_name,
  101.                     USER * sender, const char *fmt, ...)
  102. {
  103.     va_list ap;
  104.     char    reason[128];
  105.  
  106.     ASSERT (Max_Reason <= (int) sizeof (reason));
  107.     va_start (ap, fmt);
  108.     vsnprintf (reason, sizeof (reason), fmt, ap);
  109.     va_end (ap);
  110.  
  111.     pass_message_args (con, MSG_CLIENT_KILL, ":%s %s \"%s\"",
  112.                        sender_name, user->nick, reason);
  113.  
  114.     notify_mods (KILLLOG_MODE, "%s%s killed %s: %s",
  115.                  !sender ? "Server " : "", sender_name, user->nick, reason);
  116.  
  117.     /* forcefully close the client connection if local, otherwise remove
  118.      * from global user list
  119.      */
  120.     if (ISUSER (user->con))
  121.     {
  122.         const char *who;
  123.  
  124.         if (sender && sender->cloaked && user->level < LEVEL_MODERATOR)
  125.             who = "Operator";
  126.         else
  127.             who = sender_name;
  128.         send_cmd (user->con, MSG_SERVER_NOSUCH,
  129.                   "You have been killed by%s %s: %s",
  130.                   !sender ? " server " : "", who, reason);
  131.         send_cmd (user->con, MSG_SERVER_DISCONNECTING, "0");
  132.         user->con->killed = 1;  /* don't generate a QUIT message */
  133.         destroy_connection (user->con);
  134.     }
  135.     else
  136.     {
  137.         /* user is on remote server */
  138.         hash_remove (Users, user->nick);
  139.     }
  140. }
  141.  
  142. struct gkilldata
  143. {
  144.     char   *reason;
  145.     USER   *sender;
  146.     unsigned int ip;
  147.     CONNECTION *con;
  148. };
  149.  
  150. static void
  151. mkill_user_cb (USER * user, struct gkilldata *data)
  152. {
  153.     if (user->ip == data->ip)
  154.     {
  155.         if (data->sender && user->level >= data->sender->level &&
  156.             data->sender->level < LEVEL_ELITE)
  157.         {
  158.             ASSERT (ISUSER (data->sender->con));
  159.             send_cmd (data->sender->con, MSG_SERVER_NOSUCH,
  160.                       "kill failed: permission denied");
  161.             return;
  162.         }
  163.         kill_user_internal (data->sender->con, user, data->sender->nick,
  164.                             data->sender, "%s", data->reason);
  165.     }
  166. }
  167.  
  168. /* 10122 <ip> ["reason"]
  169.  * mass kill by ip address
  170.  */
  171. HANDLER (mass_kill)
  172. {
  173.     char   *av[2];
  174.     int     ac;
  175.     unsigned int   longip;
  176.     struct gkilldata data;
  177.  
  178.     (void) tag;
  179.     (void) len;
  180.     ASSERT (validate_connection (con));
  181.     CHECK_USER_CLASS ("mass_kill");
  182.     if (con->user->level < LEVEL_MODERATOR)
  183.     {
  184.         permission_denied (con);
  185.         return;
  186.     }
  187.     ac = split_line (av, FIELDS (av), pkt);
  188.     if (ac < 1)
  189.     {
  190.         unparsable (con);
  191.         return;
  192.     }
  193.     longip = inet_addr (av[0]);
  194.     if (longip == (u_int) - 1)
  195.     {
  196.         if (ISUSER (con))
  197.             send_cmd (con, MSG_SERVER_NOSUCH,
  198.                       "kill failed: invalid ip specified %s", av[0]);
  199.         return;
  200.     }
  201.     if (ac > 1)
  202.         truncate_reason (av[1]);
  203.     data.reason = (ac > 1) ? av[1] : "mkill by ip";
  204.     data.ip = longip;
  205.     data.sender = con->user;
  206.  
  207.     /* we generate a kill message for each killed user rather than passing
  208.      * the mass kill message.
  209.      */
  210.     hash_foreach (Users, (hash_callback_t) mkill_user_cb, &data);
  211. }
  212.